home *** CD-ROM | disk | FTP | other *** search
-
- /* Written by Peter Ekberg, peda@lysator.liu.se */
-
- #ifdef HAVE_CONFIG_H
- # include "config.h"
- #endif
-
- #ifdef HAVE_UNISTD_H
- # include <unistd.h>
- #endif
-
- #if defined(HAVE_GETOPT_H) && defined(HAVE_GETOPT_LONG_ONLY)
- # include <getopt.h>
- #elif !defined(HAVE_GETOPT_LONG_ONLY)
- # include "getopt.h"
- #endif
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <time.h>
- #include <ctype.h>
- #include <math.h>
-
- #include "thrust_t.h"
- #include "thrust.h"
- #include "hiscore.h"
- #include "graphics.h"
- #include "fast_gr.h"
- #include "gr_drv.h"
- #include "font5x5.h"
- #include "things.h"
- #include "conf.h"
- #include "init.h"
- #include "level.h"
- #include "keyboard.h"
- #include "options.h"
-
- #ifdef HAVE_SOUND
- # include "soundIt.h"
-
- # define CHAN_1 0
- # define CHAN_2 1
- # define CHAN_3 2
- # define CHAN_4 3
- # define SND_BOOM 0
- # define SND_BOOM2 1
- # define SND_HARP 2
- # define SND_THRUST 3
- # define SND_ZERO 4
- #endif
-
- byte *bulletmap;
- byte *blocks;
- byte *ship;
- byte *shieldship;
- byte *bana;
- byte *fuelmap;
- byte *loadmap;
- byte *shipstorage;
- byte *bulletstorage;
- byte *fragmentstorage;
- byte *fuelstorage;
- byte *loadstorage;
- byte *wirestorage;
-
- word lenx; /* x-size of level */
- word leny; /* y-size of level */
- word lenx3, leny3;
- /* Status of game. */
- double alpha, deltaalpha;
- word loaded, loadcontact, loadpointshift;
- int loadpoint;
- int countdown;
- word crash, shoot, repetetive;
- word refueling;
- int speedx, speedy;
- long absspeed, oldabs;
- int kdir, dir;
- int shipdx, shipdy;
- int x, y; /* Top left corner, 8 units per pixel. */
- int pixx, pixy; /* Top left corner in pixels. */
- int pblockx, pblocky; /* Top left corner in blocks (8x8 pixels). */
- int vx, vy; /* Speed of the ship. */
- int bildx, bildy; /* Top left corner of backing store (in pixels). */
- int bblockx, bblocky; /* Top left corner of backing store (in blocks). */
- int loadbx, loadby; /* Position of the load (in blocks). */
- int gravity;
- int score;
- byte shield;
- byte colorr, colorg, colorb;
- int nodemo=0;
- int Thrust_Is_On=0;
- int play_sound=1;
- double gamma_correction=1.0;
- int skip_frames=0;
-
- #define checkfork(b, a) \
- case b-1: \
- if(easyrider==a || easyrider==a+1) \
- easyrider=a+1; \
- else if(easyrider!=9) \
- easyrider=-1; \
- break
-
- int
- insideblock(int blkx, int blky, int pblkx, int pblky,
- int sx, int sy)
- {
- return((blkx>=pblkx-sx) && (blkx<pblkx+BBILDX) &&
- (blky>=pblky-sy) && (blky<pblky+BBILDY));
- }
-
- int
- insidepixel(int x, int y, int pixx, int pixy, int sx, int sy)
- {
- return((x>pixx-sx) && (x<pixx+PUSEX) &&
- (y>pixy-sy) && (y<pixy+PUSEY));
- }
-
- void
- updateborder(int pblkx, int pblky, int bblkx, int bblky,
- int vx, int vy)
- {
- word k;
-
- if(vy<=0) /* update bottom border */
- for(k=0; k<BBILDX; k++)
- putblock(bblkx+k, (bblky+BBILDY-1)%BBILDY, blocks+
- (*(bana+(pblkx+k)%lenx+((pblky+BBILDY-1)%leny)*lenx)<<6));
- else /* update top border */
- for(k=0; k<BBILDX; k++)
- putblock(bblkx+k, bblky, blocks+
- (*(bana+(pblkx+k)%lenx+(pblky%leny)*lenx)<<6));
- if(vx>0) /* update right border */
- for(k=0; k<BBILDY; k++)
- putblock(bblkx+BBILDX-1, (bblky+k)%BBILDY, blocks+
- (*(bana+(pblkx+BBILDX-1)%lenx+((pblky+k)%leny)*lenx)<<6));
- else /* update left border */
- for(k=0; k<BBILDY; k++)
- putblock(bblkx, (bblky+k)%BBILDY, blocks+
- (*(bana+pblkx%lenx+((pblky+k)%leny)*lenx)<<6));
- }
-
- void
- pause_message(void)
- {
- char *str[] = {
- "Game paused.",
- "Press 'C' to continue..." };
-
- chflag=1;
- gcenter(80, str[0]);
- gcenter(91, str[1]);
- chflag=0;
- displayscreen();
- }
-
- void
- escape_message(void)
- {
- char *str[] = {
- "Are you sure you want to quit (Y/N)?" };
-
- chflag=1;
- gcenter(85, str[0]);
- chflag=0;
- displayscreen();
- }
-
- byte
- whatkeys(void)
- {
- byte keys;
-
- /* Use this to create a demo.
- * Don't forget to uncomment the fputc statement below.
- */
- /*
- static FILE *f=NULL;
- if(f == NULL)
- f=fopen("foobarfoo", "w");
- */
-
- keys = getkeys();
-
- /*
- fputc((keys&escape_bit)?quit_bit:keys, f);
- */
- return(keys);
- }
-
- byte
- nextmove(int reset)
- {
- static byte *p;
- byte retbits=0;
-
- if(reset) {
- keywaiting();
- p=&bin_demomove[0];
- }
- else if(keywaiting()) {
- retbits=quit_bit;
- flushkeyboard();
- }
- else {
- retbits=*(p++);
- retbits&=~thrust_bit;
- retbits|=*(p-!!(random()%20)) & thrust_bit;
- }
-
- return(retbits);
- }
-
- void
- gamestatusframe(void)
- {
- int i, maxx;
-
- for(i=3; i<317; i++)
- putpixel(i, 3, 0x88);
- for(i=3; i<11; i++) {
- putpixel( 3, i, 0x88);
- putpixel( 4, i, 0x88);
- putpixel(315, i, 0x88);
- putpixel(316, i, 0x88);
- }
- for(i=3; i<11; i++) {
- putpixel( i, i+8, 0x88);
- putpixel( 1+i, i+8, 0x88);
- putpixel(318-i, i+8, 0x88);
- putpixel(319-i, i+8, 0x88);
- }
- for(i=9; i<311; i++)
- putpixel(i, 18, 0x88);
- maxx = 80-gstrlen("FUEL")-2;
- for(i=6; i<maxx; i++) {
- putpixel(i, 6, 65);
- putpixel(i, 8, 65);
- }
- maxx = 160-gstrlen("LIVES")/2-2;
- for(i=82; i<maxx; i++) {
- putpixel(i, 6, 65);
- putpixel(i, 8, 65);
- }
- maxx = 280-gstrlen("SCORE")-2;
- for(i=160+gstrlen("LIVES")/2+2; i<maxx; i++) {
- putpixel(i, 6, 65);
- putpixel(i, 8, 65);
- }
- for(i=282; i<313; i++) {
- putpixel(i, 6, 65);
- putpixel(i, 8, 65);
- }
- chcolor = 0x89;
- printgs(80-gstrlen("FUEL"), 5, "FUEL");
- gcenter(5, "LIVES");
- printgs(280-gstrlen("SCORE"), 5, "SCORE");
- chcolor = TEXTCOLOR;
- }
-
- void
- gamestatus(int lives, int fuel, int score)
- {
- static char textstr[40];
-
- chcolor = 0x88;
- drawfuel(fuel);
- sprintf(textstr, "%d", lives);
- gcenter(12, textstr);
- sprintf(textstr, "%d", score);
- printgs(280-gstrlen(textstr), 12, textstr);
- chcolor = TEXTCOLOR;
- }
-
- int
- game(int demo)
- {
- byte actionbits=0;
- double ax, ay, aradial, acircum;
- word lives, endlevel;
- word dying;
- word alive;
- word fuel;
- int l;
- int level;
- int round;
- static char **levels[LEVELS]
- = { level1, level2, level3, level4, level5, level6 };
- static char textstr[40];
- int localscore;
- options end;
- int ch;
- int lastlevel;
- int easyrider=0;
- int restartx=0, restarty=0;
- int loadedrestart=0;
- restartpoint *restartxy;
- int gravitymsg;
- int visibilitymsg;
- int teleport;
-
- if(demo)
- nextmove(1);
-
- lives=3; /* 3 */
- localscore=0;
- score=0;
- round=0; /* 0 */
- level=0; /* 0 */
- lastlevel=-1;
- shield=0;
- fuel=1000; /* 1000 */
- gravitymsg=0;
- visibilitymsg=0;
- teleport=0;
-
- while(level<LEVELS && lives>0 && fuel) {
- #ifdef DEBUG2
- printf("Newlevel: %d\n", level);
- #endif
- endlevel = 0;
- dying = 0;
- alive = 1;
-
- srandom(time(NULL));
- if(level!=lastlevel || !powerplant) {
- if(level==0 && lastlevel>0) {
- gravitymsg = 1;
- if(round == 2)
- visibilitymsg = 1;
- }
- if(!readbana(levels[level])) {
- printf("Illegal definition of level %d.\n", level+1);
- return(1);
- }
- restartx = (lenx+restartpoints[0].x-(154>>3))%lenx;
- restarty = restartpoints[0].y-(82>>3)-4*(round&1);
- loadedrestart = 0;
- initgame(round, 1, restartx, restarty);
- }
- else {
- loaded = loadedrestart;
- initgame(round, 0, restartx, restarty);
- }
-
- initscreen(round);
- putscr(pixx%PBILDX, pixy%PBILDY, 1);
- lastlevel = level;
-
- gamestatusframe();
- gamestatus(lives, fuel, score);
- sprintf(textstr, "Level %d", level+1);
- gcenter(70, textstr);
- if(gravitymsg) {
- gcenter(60, (round&1) ? "Reversed gravity" : "Normal gravity");
- if(visibilitymsg)
- gcenter(52, (round&2) ? "Invisible ground" : "Visible ground");
- }
- displayscreen();
- syncscreen();
- fade_in();
- usleep(1000000UL + 2000000UL*gravitymsg);
- gravitymsg=0;
- syncscreen();
- putscr(pixx%PBILDX, pixy%PBILDY, 1);
- drawteleport(1);
- displayscreen();
- while(!endlevel) {
- actionbits=demo ? nextmove(0) : whatkeys();
-
- if(actionbits&quit_bit) {
- #ifdef DEBUG2
- printf("Endlevel: User pressed quit-key\n");
- #endif
- endlevel=1;
- }
-
- if(actionbits&pause_bit) {
- #ifdef HAVE_SOUND
- if(play_sound) {
- Thrust_Is_On=0;
- Snd_effect(SND_ZERO, CHAN_1);
- }
- #endif
- pause_message();
- singlekey();
- end=NOTHING;
- while(getkey());
- while(end==NOTHING) {
- ch=getkey();
- switch(tolower(ch)) {
- case 'p':
- if(easyrider!=9)
- easyrider=0;
- break;
- case 't':
- checkfork('m', 0);
- checkfork('b', 1);
- checkfork('z', 2);
- checkfork('h', 3);
- checkfork('s', 4);
- checkfork('p', 5);
- checkfork('v', 6);
- checkfork('o', 7);
- checkfork('e', 8);
- break;
- case 'c':
- case 'q':
- case 27:
- end=PLAY;
- break;
- }
- usleep(50000UL);
- }
- if(easyrider!=9)
- easyrider=0;
- multiplekeys();
- }
- if(actionbits&escape_bit) {
- #ifdef HAVE_SOUND
- if(play_sound) {
- Thrust_Is_On=0;
- Snd_effect(SND_ZERO, CHAN_1);
- }
- #endif
- escape_message();
- singlekey();
- end=NOTHING;
- while(end==NOTHING) {
- ch=getkey();
- switch(tolower(ch)) {
- case 'y':
- end=END;
- #ifdef DEBUG2
- printf("Endlevel: User answered yes efter ESC.\n");
- #endif
- endlevel=1;
- level=LEVELS;
- break;
- case 'n':
- end=PLAY;
- break;
- }
- usleep(50000UL);
- }
- multiplekeys();
- }
- if(alive && (actionbits&right_bit)) {
- decr(kdir, 0, 96);
- dir=kdir/3;
- }
- if(alive && (actionbits&left_bit)) {
- incr(kdir, 96, 0);
- dir=kdir/3;
- }
- if(alive && (actionbits&fire_bit)) {
- if(!shoot) {
- shoot=1;
- newbullet(x+((160+shipdx)<<3)+74*cos(dir * M_PI/16),
- y+(( 88+shipdy)<<3)-74*sin(dir * M_PI/16),
- speedx/256.0+32*cos(dir * M_PI/16),
- speedy/256.0+32*sin(dir * M_PI/16),
- kdir/6, 1);
- }
- else if(repetetive || easyrider)
- shoot=0;
- }
- else
- shoot=0;
- refueling=0;
- if(alive && (actionbits&pickup_bit)) {
- if(fuel>0) {
- if(shield++==3) {
- #if !(defined(DEBUG) || defined(DEBUG2))
- if(!easyrider)
- fuel--;
- #endif
- shield=1;
- }
- }
- else
- shield=0;
- l=closestfuel((pixx+shipdx+160)%lenx3,
- (pixy+shipdy+88)%leny3);
- if(l>=0)
- if(resonablefuel((pixx+shipdx+160)%lenx3,
- (pixy+shipdy+88)%leny3, l)) {
- #ifndef DEBUG
- if(!easyrider)
- fuel+=6;
- #endif
- refueling=1;
- things[l].alive--;
- if(things[l].alive==1)
- things[l].score=300;
- }
- if(!loaded)
- if(inloadcontact((pixx+shipdx+160)%lenx3,
- (pixy+shipdy+88)%leny3)) {
- loadcontact=1;
- *(bana+lenx*loadby+loadbx)=32;
- drawload(0);
- }
- }
- else {
- shield=0;
- if(alive && loadcontact) {
- *(bana+lenx*loadby+loadbx)=109;
- drawload(1);
- loadcontact=0;
- }
- }
- if(alive && (actionbits&thrust_bit)) {
- if(fuel>0) {
- #ifdef HAVE_SOUND
- if(play_sound)
- if(Thrust_Is_On==0) {
- Thrust_Is_On=1;
- Snd_effect(SND_THRUST, CHAN_1);
- }
- #endif
- #if !(defined(DEBUG) || defined(DEBUG2))
- if(!easyrider)
- fuel--;
- #endif
- oldabs=speedx*(long)speedx+speedy*(long)speedy;
-
- if(loaded) { /* Ship and blob */
- aradial = cos(dir * M_PI/16 - alpha);
- acircum = sin(dir * M_PI/16 - alpha);
- ax =
- SPEED/2
- * (aradial*cos(alpha) - acircum*sin(alpha)/(1 + REL_MASS))
- / (1 + REL_MASS);
- ay =
- SPEED/2
- * (aradial*sin(alpha) - acircum*cos(alpha)/(1 + REL_MASS))
- / (1 + REL_MASS);
- deltaalpha += SPEED/2 * acircum * M_PI/262144;
- }
- else { /* Ship, no blob */
- ax=SPEED*cos(dir * M_PI/16) / 2;
- ay=SPEED*sin(dir * M_PI/16) / 2;
- }
-
- speedx+=ax;
- speedy+=ay;
- absspeed=speedx*(long)speedx+speedy*(long)speedy;
- if(absspeed>1000000000L && absspeed>oldabs) {
- speedx-=ax;
- speedy-=ay;
- }
- }
- else {
- #ifdef HAVE_SOUND
- if(play_sound)
- if(Thrust_Is_On == 1) {
- Snd_effect(SND_ZERO, CHAN_1);
- Thrust_Is_On = 0;
- }
- #endif
- }
- }
- else {
- #ifdef HAVE_SOUND
- if(play_sound)
- if(Thrust_Is_On == 1) {
- Snd_effect(SND_ZERO, CHAN_1);
- Thrust_Is_On = 0;
- }
- #endif
- }
- if(loaded) {
- if(loadpointshift) {
- speedx+=shipdx*12;
- speedy+=shipdy*12;
- }
- alpha+=deltaalpha;
- if(alpha>2*M_PI)
- alpha-=2*M_PI;
- if(alpha<0)
- alpha+=2*M_PI;
- loadpointshift=0;
- if(++loadpoint>126)
- loadpoint=126;
- else
- loadpointshift=1;
- shipdx= cos(alpha)*loadpoint/5.90625;
- shipdy=-sin(alpha)*loadpoint/5.90625;
- if(loadpointshift) {
- speedx-=shipdx*12;
- speedy-=shipdy*12;
- }
- deltaalpha-=deltaalpha/1024;
- }
- else
- shipdx=shipdy=0;
- /* Gravity and Aerodynamics */
- if(speedx>0)
- speedx=speedx-(speedx>>9)-1;
- else if(speedx<0)
- speedx=speedx-(speedx>>9)+1;
- if(alive) {
- if(gravity>=0)
- speedy-=(SPEED*gravity+1)>>8;
- else
- speedy-=(SPEED*gravity>>8)+1;
- if(speedy>0)
- speedy--;
- else if(speedy<0)
- speedy++;
- /* Move the Ship */
- speedx=min(speedx, 16384);
- speedx=max(speedx, -16384);
- speedy=min(speedy, 16384);
- speedy=max(speedy, -16384);
- if(speedx>=0)
- vx=(speedx+1)>>8;
- else
- vx=(speedx>>8)+1;
- if(speedy>=0)
- vy=(speedy+1)>>8;
- else
- vy=(speedy>>8)+1;
- x=(x+vx+(lenx<<6))%(lenx<<6);
- y=(y-vy+(leny<<6))%(leny<<6);
- }
-
- /* Bunkerfire */
- if(!ppblip)
- bunkerfirebullets();
- movebullets();
- movefragments();
- drawfuel(fuel);
-
- /* Move the Power Plant blip */
- ppcount=(ppcount+1)&15;
- if(!ppcount && powerplant && ppblip)
- ppblip--;
-
- if(!powerplant) {
- countdown--;
- if(countdown<0) {
- #ifndef DEBUG
- if(alive && !easyrider) {
- dying=1;
- #ifdef DEBUG2
- printf("Dying: Power Plant countdown.\n");
- #endif
- }
- #endif
- }
- else {
- chflag=1;
- sprintf(textstr, "%d ", (countdown+99)/100);
- printgs(105, 12, textstr);
- printgs(205, 12, textstr);
- chflag=0;
- }
- }
-
- /* Precalculate some values */
- pixx=x>>3;
- pixy=y>>3;
- bildx=(pixx+PBILDX-4)%PBILDX+4;
- bildy=pixy%PBILDY;
- pblockx=pixx>>3;
- pblocky=pixy>>3;
- bblockx=bildx>>3;
- bblocky=bildy>>3;
-
- if(pblocky>leny-3) {
- endlevel=1;
- #ifdef DEBUG2
- printf("Endlevel: Finished level.\n");
- #endif
- teleport=1;
- y=0;
- pixy=0;
- pblocky=0;
- }
-
- /* Check if at a restart barrier. If so, update the restart point. */
- restartxy=atbarrier((pblockx+((154+shipdx)>>3))%lenx,
- pblocky+((82+shipdy)>>3));
- if(restartxy) {
- restartx=(lenx+restartxy->x-(154>>3))%lenx;
- restarty=restartxy->y-(82>>3);
- loadedrestart=loaded;
- }
-
- /* Scroll the screen */
- updateborder(pblockx, pblocky, bblockx, bblocky, vx, vy);
-
- drawpowerplantblip();
- drawbullets();
- if(alive)
- crash=drawshuttle();
- drawfragments();
- if(alive && refueling)
- drawfuellines();
- /* Check if end of life. */
- #ifndef DEBUG
- if(!easyrider)
- if(alive && crash) {
- lives--;
- dying=1;
- #ifdef DEBUG2
- printf("Dying: Crashing.\n");
- #endif
- }
- #endif
- /* Wait for the screen retrace and then dump the graphics to it. */
- /* Screendump */
-
- syncscreen();
- putscr(bildx, bildy, 0);
- displayscreen();
-
- /* Remove moveable objects from screen in reverse order. */
- if(alive && refueling)
- undrawfuellines();
- undrawfragments();
- if(alive)
- undrawshuttle();
- undrawbullets();
-
- /* Remove objects */
- if(!easyrider)
- localscore+=killdyingthings();
- else
- killdyingthings();
- if(dying) {
- alive=0;
- dying=0;
- #ifdef HAVE_SOUND
- if(play_sound) {
- Snd_effect(SND_ZERO, CHAN_1);
- Thrust_Is_On=0;
- Snd_effect(SND_BOOM2, CHAN_2);
- }
- #endif
- explodeship();
- }
- if(!alive && !livefragments()) {
- #ifdef HAVE_SOUND
- if(play_sound) {
- Snd_effect(SND_ZERO, CHAN_1);
- Thrust_Is_On=0;
- }
- #endif
- endlevel=1;
- #ifdef DEBUG2
- printf("Endlevel: Shit crashed.\n");
- #endif
- }
- animatesliders();
- if(localscore>score) {
- chflag=1;
- if(localscore/10000 > score/10000)
- lives++;
- score=localscore;
- gamestatus(lives, fuel, score);
- chflag=0;
- }
- }
- if(teleport) {
- #ifdef HAVE_SOUND
- if(play_sound)
- Snd_effect(SND_ZERO, CHAN_1);
- #endif
- bin_colors[65*3+0]=GAMMA(colorr);
- bin_colors[65*3+1]=GAMMA(colorg);
- bin_colors[65*3+2]=GAMMA(colorb);
- fadepalette(0, 255, bin_colors, 64, 1);
- drawteleport(0);
- }
-
- if(!(actionbits&(quit_bit|escape_bit)))
- usleep(1000000UL);
- fade_out();
-
- if(!demo && !(actionbits&(quit_bit|escape_bit))) {
- if(teleport || !powerplant) {
- chflag=1;
- gamestatusframe();
- gamestatus(lives, fuel, score);
-
- if(!powerplant) {
- sprintf(textstr, "Planet destroyed");
- gcenter(61, textstr);
- }
-
- if(teleport && loaded)
- sprintf(textstr, "Mission %d complete", level+1);
- else if(powerplant)
- sprintf(textstr, "Mission incomplete");
- else
- sprintf(textstr, "Misson %d failed", level+1);
- gcenter(73-6*(teleport && loaded && powerplant), textstr);
-
- if((teleport && loaded) || !powerplant) {
- if(teleport && loaded)
- sprintf(textstr, "Bonus %d", 4000+400*level-2000*powerplant);
- else
- sprintf(textstr, "No bonus");
- gcenter(85-6*(!!powerplant), textstr);
- }
-
- displayscreen();
- fade_in();
- usleep(2000000UL);
- if(!easyrider && teleport && loaded)
- localscore+=4000+400*level-2000*powerplant;
- if((teleport && loaded) || !powerplant) {
- if(++level==LEVELS) {
- level=0;
- round=(round+1)%4;
- }
- }
- if(localscore/10000 > score/10000)
- lives++;
- score=localscore;
- gamestatus(lives, fuel, score);
- chflag=0;
- displayscreen();
- usleep(2000000UL);
- fade_out();
- }
- }
- teleport=0;
-
- if(demo)
- level=LEVELS;
- }
-
- if(!demo) {
- chflag=1;
- gamestatusframe();
- gamestatus(lives, fuel, score);
-
- gcenter(73, "Game Over");
-
- displayscreen();
- fade_in();
- usleep(2000000UL);
- fade_out();
- }
-
- return(0);
- }
-
- void
- pressanykey(void)
- {
- singlekey();
-
- do
- usleep(50000UL);
- while(!getkey());
-
- multiplekeys();
- }
-
- int
- instructions(void)
- {
- int i;
- static char *keys[] = {
- "Esc", "P", "C" };
- static char *func[] = {
- "Turn left", "Turn right", "Thrust", "Fire",
- "Pick up & Shield", "Quit Game (Q=Esc)", "Pause", "Continue" };
- static char *story[] = {
- "The resistance is about to launch a major offensive against",
- "the Intergalactic Empire. In preparation for this, they have",
- "captured several battle-grade starships, but they lack the",
- "essential power sources for these formidable craft; Klystron",
- "Pods. You have been commissioned by resistance to steal these",
- "pods from the Empire's storage planets. Each planet is",
- "defended by a battery of 'Limpet' guns, powered by a nuclear",
- "power plant. By firing shots at the power plant, the guns can",
- "be temporarily disabled; the more shots fired at the nuclear",
- "reactor, the longer the guns will take to recharge.",
- "BUT BEWARE!! If you fire too many shots at the reactor, it",
- "will become critical, giving you just ten seconds to clear",
- "the plantet before it is destroyed. If you have not already",
- "retrieved the pod stored at the planet, then you will have",
- "failed the mission. If you have retrieved the pod, and you",
- "manage to send the reactor into its critical phase, and",
- "leave the planet safely, you will receive a hefty bonus.",
- NULL };
- static char *score[] = {
- "Destroying a limpet gun:",
- "Destroying a fuel cell:",
- "Picking up a fuel cell:",
- "Bonus for destroying planet:",
- "",
- "A spare ship is allocated for every:"
- };
- static char *scores[] = {
- "750",
- "150",
- "300",
- "2000 + Mission Bonus",
- "",
- "10000"
- };
-
- chcolor = HIGHLIGHT;
- gcenter(20, "THE SILLY STORY!");
- chcolor = TEXTCOLOR;
- for(i=0; story[i]; i++)
- gcenter(35 + i*8, story[i]);
-
- gcenter(180, "Press any key for the next page.");
-
- fade_in();
- pressanykey();
- fade_out();
-
- chcolor = HIGHLIGHT;
- gcenter(40, "SCORING");
- chcolor = TEXTCOLOR;
- for(i=0; i<6; i++) {
- chcolor = TEXTCOLOR;
- printgs(200-gstrlen(score[i]), 65 + 8*i, score[i]);
- chcolor = HIGHLIGHT;
- printgs(205, 65 + 8*i, scores[i]);
- }
-
- chcolor = TEXTCOLOR;
- gcenter(130, "Press any key for the next page.");
-
- fade_in();
- pressanykey();
- fade_out();
-
- gcenter(50, "The following keys are used:");
- for(i=0; i<8; i++) {
- chcolor = HIGHLIGHT;
- if(i<5)
- printgs(140-gstrlen(keystring(scancode[i])),
- 63+i*8+2*(i>4),
- keystring(scancode[i]));
- else
- printgs(140-gstrlen(keys[i-5]), 63+i*8+2*(i>4), keys[i-5]);
- chcolor = TEXTCOLOR;
- printgs(145, 63+i*8+2*(i>4), func[i]);
- }
- gcenter(150, "Press any key for the main menu.");
-
- fade_in();
- pressanykey();
- fade_out();
-
- return(0);
- }
-
- int
- about(void)
- {
- int i;
- static char *str[] = {
- "Thrust version " VERSION,
- "",
- "Written by",
- "",
- "Peter Ekberg",
- "peda@lysator.liu.se",
- "",
- #ifdef AMIGA
- "Amiga Ports (M68k, PowerPC) by",
- "Frank Wille",
- "frank@phoenix.owl.de",
- "",
- #endif
- "Thanks to the authors",
- "of the original",
- "for the C64.",
- NULL
- };
-
- for(i=0; str[i]; i++) {
- #ifdef AMIGA
- if (i==5 || i==9)
- #else
- if(i==5)
- #endif
- chcolor = HIGHLIGHT;
- else
- chcolor = TEXTCOLOR;
- #ifdef AMIGA
- gcenter(10+9*i, str[i]);
- #else
- gcenter(40+9*i, str[i]);
- #endif
- }
- gcenter(145, "Press any key for the main menu.");
-
- fade_in();
- pressanykey();
- fade_out();
-
- return(0);
- }
-
- char *
- enterhighscorename(void)
- {
- static char name[40];
- char str[40];
-
- strcpy(name, standardname());
- sprintf(str, "You managed %d points!", score);
- gcenter(64, str);
- gcenter(75, "You made it into the highscore list!");
- gcenter(86, "Enter your name:");
- printgs(130, 97, name);
- fade_in();
-
- singlekey();
-
- if(readgs(130, 97, name, 39, 80, 0)==-1)
- strcpy(name, standardname());
-
- multiplekeys();
-
- fade_out();
-
- return(name);
- }
-
- int
- showhighscores(void)
- {
- char str[100];
- byte tmp=chcolor;
- int i;
- int scorew, namew;
- int len;
-
- gcenter(50, "The current highscores are");
-
- scorew=namew=0;
- for(i=0; i<HIGHSCORES; i++) {
- sprintf(str, "%d", highscorelist[i].score);
- len=gstrlen(str);
- if(len>scorew)
- scorew=len;
- len=gstrlen(highscorelist[i].name);
- if(len>namew)
- namew=len;
- }
-
- for(i=0; i<HIGHSCORES; i++) {
- sprintf(str, "%d", highscorelist[i].score);
- chcolor = SCORETEXT;
- printgs(155+(scorew-namew)/2-gstrlen(str), 70+11*i, str);
- chcolor = SCORENAME;
- printgs(165+(scorew-namew)/2, 70+11*i, highscorelist[i].name);
- }
-
- chcolor=tmp;
- gcenter(145, "Press any key for the main menu.");
-
- fade_in();
- pressanykey();
- fade_out();
-
- return(0);
- }
-
- void
- newhighscore(void)
- {
- char *name;
-
- name = enterhighscorename();
- inserthighscore(name, score);
- writehighscores();
- showhighscores();
- }
-
- options
- menu(void)
- {
- int i;
- options end=NOTHING;
- int ch;
- static char *menuchoises[NOTHING]= { "I", "C", "H", "P", "A", "Q" };
- static char *menuoptions[NOTHING]= {
- "Instructions", "Configuration", "Highscores",
- "Play Game", "About", "Quit" };
- int count=0;
-
- clearscr();
- putarea(title_pixels, 0, 0, title_cols, title_rows, title_cols,
- (PUSEX-title_cols)>>1, (PUSEY+24-title_rows)>>1);
- for(i=0; i<NOTHING; i++) {
- chcolor = TEXTCOLOR;
- printgs(20, 134+i*11, menuoptions[i]);
- chcolor = HIGHLIGHT;
- printgs(20, 134+i*11, menuchoises[i]);
- }
- printgs(60, 35, "GRATTIS CALLE!");
- chcolor = TEXTCOLOR;
-
- fade_in();
- singlekey();
-
- while(end==NOTHING) {
- ch=getkey();
- switch(tolower(ch)) {
- case 0:
- break;
- case 'i':
- end=INST;
- break;
- case 'p':
- end=PLAY;
- break;
- case 'h':
- end=HI;
- break;
- case 'a':
- end=ABOUT;
- break;
- case 'c':
- end=CONF;
- break;
- case 'd':
- end=DEMO;
- break;
- case 'q':
- case 27:
- end=END;
- break;
- default:
- count=0;
- break;
- }
- usleep(50000UL);
-
- if(++count==160 && end==NOTHING) {
- if(!nodemo)
- end=DEMO;
- count=0;
- }
- }
-
- multiplekeys();
- fade_out();
-
- return(end);
- }
-
- int
- main(int argc, char **argv)
- {
- int end=0;
- int optc;
-
- do {
- static struct option longopts[] = {
- OPTS,
- SVGA_OPTS,
- X_OPTS,
- { 0, 0, 0, 0 }
- };
-
- optc=getopt_long_only(argc, argv,
- OPTC SVGA_OPTC X_OPTC, longopts, (int *)0);
- switch(optc) {
- case 's': /* --svgamode */
- case 'm': /* --noshm */
- case 'X': /* -display */
- case 'g': /* -geometry */
- case '2': /* --double */
- break;
- case 'e': /* --nosoundeffects */
- play_sound=0;
- break;
- case 'd': /* --nodemo */
- nodemo=1;
- break;
- case 'c': /* --gamma */
- {
- char *end;
- double tmp;
-
- if(*optarg) {
- tmp = strtod(optarg, &end);
- if(*end || tmp==HUGE_VAL || tmp<=0.0)
- tmp = 0.0;
- }
- else
- tmp = 0.0;
-
- if(tmp == 0.0)
- printf("Illegal gamma correction value: \"%s\"\n", optarg);
- else
- gamma_correction = tmp;
- }
- break;
- case 'j': /* --step */
- skip_frames = 1;
- break;
- case 'h': /* --help */
- printf("Thrust: version " VERSION " -- the Game\n");
- printf("Using %s to drive the graphics and\n"
- " %s to drive the keyboard.\n\n",
- graphicsname(),
- keyname());
- printf("usage: thrust [OPTION]...\n\n"
- " -v, --version\n"
- " -h, --help\n"
- " -d, --nodemo Do not run the demo.\n"
- " -e, --nosoundeffects Do not play sound effects.\n"
- " -c, --gamma=Value Gamma correction of colors.\n"
- " -j, --step Only draw every third frame (faster).\n");
- if(!strcmp(graphicsname(), "SVGA")) {
- printf(" -s, --svgamode=MODE The format of MODE is G<width>x<height>x<colors>\n");
- }
- if(!strcmp(graphicsname(), "X11")) {
- printf(" -m, --noshm Do not use shared memory (slower).\n"
- " -2, --double Double the size of the window (slower).\n"
- " -display display-name See the X man page for details.\n"
- " -geometry geom-spec See the X man page for details.\n");
- }
- printf("\n");
- exit(1);
- case 'v': /* --version */
- printf("Thrust: version " VERSION "\n");
- exit(0);
- case EOF:
- if(optind == argc)
- break;
- default:
- fprintf(stderr, "Thrust: bad usage (see 'thrust -h')\n");
- exit(1);
- }
- } while(optc != EOF);
-
- graphics_preinit();
- inithardware(argc, argv);
-
- if(!initmem()) {
- restorehardware();
- return(1);
- }
- inithighscorelist();
- initkeys();
-
- usleep(1000000L); /* phx - replaces sleep(1) */
-
- while(!end) {
- switch(menu()) {
- case INST:
- instructions();
- break;
- case PLAY:
- if(!(end=game(0)))
- if(ahighscore(score))
- newhighscore();
- break;
- case HI:
- showhighscores();
- break;
- case ABOUT:
- about();
- break;
- case CONF:
- conf();
- break;
- case DEMO:
- game(1);
- break;
- case END:
- end=1;
- break;
- default:
- break;
- }
- }
-
- restoremem();
- restorehardware();
-
- return(0);
- }
-